import { Action, ActionKey } from "@/action/Action";
import { modelService } from "../../service";
import { GraphNode } from "../../project/GraphNode";
import { MenuItem } from "@/constants/types";
import ChooseElement from "@/common/ChooseElement.vue";
import { modelTreeSelectWindow } from "../../modals/modelTreeSelect";
import { StType } from "@/constants/StType";
import { actionManager } from "@/action/ActionManager";
import { OpenCreateElementAction } from "./OpenCreateElementAction";
import { GraphModel, Shape } from "@/mdesign-lib/mdesign-graph.umd.js";
import { CreateItemFlowWindow } from "../../modals/createItemFlow";
import { SiderBarItemKey } from "../../comps/station/graphTabs/graphEditor/config/SiderBarItemKey";
import { DiagramTableEditor } from "../../comps/station/graphTabs/diagramTableNew/DiagramTableEditor";
import { MenuItem as TableMenuItem } from "../../comps/station/graphTabs/diagramTableNew/config/toolBar";

export class OpenCreateRelationAction extends Action {
  keyName = ActionKey.openCreateRelation;
  desc = "新建关系";
  bindKey = "";

  async run(ownerId: string, metaclass: string, sts: string[] = []) {
    const project = app.activeProject;
    if (!project) throw new Error("no project");
    try {
      project.attributeTabsModel.ignoreJavaModelChange = true;
      const nodeDatas = await modelService.addModel(project.id, ownerId, metaclass, sts);
      // .then((nodeDatas) => {
      //   const nodePool = app.activeProject!.nodePool;
      //   const ownerNode = nodePool.getNode(ownerId) as GraphNode;
      //   const nodeDatas = nodePool.loadNodes(ownerNode).then(() => {
      //     ownerNode.expand = true;
      //     nodeDatas.forEach(nodeData =>
      //       // 打开重命名
      //       this.actions.getAction('setNodeInEdit')!.run(nodePool.getNode(nodeData.id))
      //     );
      //     // if (modelUtil.isMetaclassDiagram(nodeData.metaclass)) {
      //     //   const node = project.nodePool.getNode(nodeData.id);
      //     //   if (node) {
      //     //     project.ui.addTab(node);
      //     //   }

      //     // }

      //   });

      // });

      const targetModel = nodeDatas.find(model => model.metaclass === metaclass); // 只判断了metaclass，目前够用
      if (targetModel) {
        await (actionManager.getAction(ActionKey.openCreateElement) as OpenCreateElementAction).afterCreateModel(targetModel.id);
        // await this.afterCreateModel(targetModel.id);
      } else {
        console.error("缺少返回模型");
      }
    } finally {
      project.attributeTabsModel.ignoreJavaModelChange = false;
    }
  }

  // 模型树上面右键点击菜单行为
  async onTreeMenuClick(graphNode: GraphNode, menuItem: MenuItem) {
    // 根据事件获取x、y的位置
    if (graphNode.disabled) return;
    // const x = 100;
    // const y = 100;
    // 需要判断选中单个模型还是多个模型
    const project = app.activeProject!;
    const selectedIds = project.nodePool.selectedNodeIds;
    if (selectedIds.length > 1) {
      this.doMenuClick(selectedIds, menuItem, menuItem.point?.x ?? 100, menuItem.point?.y ?? 100);
    } else {
      this.doMenuClick(graphNode.id, menuItem, menuItem.point?.x ?? 100, menuItem.point?.y ?? 100);
    }
  }

  // 图形上面右键点击菜单行为，和树上点击行为一致，bug:3662
  async onShapeMenuClick(graph: GraphModel, shape: Shape, menuItem: MenuItem) {
    // 需要判断选中单个图元还是多个图元
    const shapes = graph.selectionModel.selection;
    if (shapes.length > 1) {
      this.doMenuClick(
        shapes.map(it => it.modelId),
        menuItem
      );
    } else {
      this.doMenuClick(shape.modelId, menuItem);
    }
  }

  async doMenuClick(modelId: string | string[], menuItem: MenuItem, x?: number, y?: number, callback?: Function) {
    const isMultiple = Array.isArray(modelId);
    const menuList = (await this.getMenuList(modelId, menuItem.type)).filter(item => item.metaclass);
    if (!menuList?.length) return;
    const result: MenuItem = await ChooseElement.popup({
      x,
      y,
      title: "新建元素",
      list: [{ label: "常用元素", children: menuList, value: "" }]
    }).catch((err: any) => err && console.error(err));
    if (result) {
      const directionObj = {
        Incoming: "in",
        Outgoing: "out"
      };
      const relationshipType = result.appliedStereotypes ? result.appliedStereotypes[0] : result.metaclass;

      const projectId = app.activeProject!.config.id;
      const ownerParams = {
        direction: directionObj[menuItem.type],
        projectId: projectId,
        relationshipType,
        firstEndId: modelId
      };
      modelTreeSelectWindow
        .popup({
          loadMethod: "queryValidateEnds",
          showNodeLabel: true,
          loadParams: JSON.stringify({
            row: {
              checkMethod: null,
              dataType: "",
              instanceId: "",
              isMultiplicity: false,
              key: "",
              moreBtnCondition: null,
              projectId: "",
              updateMethod: null
            },
            ownerParams,
            projectId
          }),
          checkable: false,
          attrTip: "radio",
          title: "选择模型"
        })
        .then(async res => {
          if (!res.success) return;
          // 单个
          if (!isMultiple) {
            await this.createSingleRel(menuItem, modelId, res.selectedId as string, result);
          } else {
            await this.createMultipleRel(menuItem, modelId, res.selectedId as string, result);
          }

          if (callback) {
            await callback();
          }
        })
        .finally(() => {});
    }
  }

  async getMenuList(modelId: string | string[], type: string) {
    const menus = await modelService.getCanCreateRelationTypes(app.activeProject!.id, modelId, type);
    // TODO 多选情况下暂时屏蔽项流
    if (Array.isArray(modelId)) return menus.filter(it => it.value !== "ItemFlow");

    return menus;
  }

  async onTableToolbarClick(tableEditor: DiagramTableEditor, menuItem: TableMenuItem) {
    const modelId = tableEditor.tableModel.selectedCells[0].rowId;
    if (!modelId) return;
    this.doMenuClick(modelId, menuItem as any as MenuItem, menuItem.point?.x ?? 100, menuItem.point?.y ?? 100);
  }

  /**
   * 创建单一关系
   * @param menuItem 出/入方向
   * @param modelId
   * @param selectedId 选定的关系类型
   * @param relResult 选定的来源/目标结果
   * @returns
   */
  async createSingleRel(menuItem: MenuItem, modelId: string, selectedId: string, relResult: MenuItem) {
    // sourcemodel targetmodel metaclass stereotype projectId
    const obj = {
      sourceId: "",
      targetId: ""
    };
    if (menuItem.type === "Outgoing") {
      obj.sourceId = modelId;
      obj.targetId = selectedId as string;
    } else {
      obj.sourceId = selectedId as string;
      obj.targetId = modelId;
    }
    if (relResult.value === SiderBarItemKey.ItemFlow) {
      CreateItemFlowWindow.popup({
        projectId: app.activeProject!.config.id,
        parentId: app.activeProject!.ui.activeTabId,
        connectorModelId: undefined,
        firstEndId: obj.sourceId,
        secondEndId: obj.targetId
      });
      return;
    }
    await modelService.createRelation({
      sourceId: obj.sourceId,
      targetId: obj.targetId,
      metaclass: relResult.metaclass,
      stereotype: (relResult.appliedStereotypes as StType[]) || [],
      projectId: app.activeProject!.config.id,
      value: relResult.value
    });
  }

  /**
   * 创建多对一关系
   * @param menuItem 出/入方向
   * @param modelIds
   * @param selectedId 选定的关系类型
   * @param relResult 选定的来源/目标结果
   * @returns
   */
  async createMultipleRel(menuItem: MenuItem, modelIds: string[], selectedId: string, relResult: MenuItem) {
    // sourcemodel targetmodel metaclass stereotype projectId
    const obj = {
      source: "",
      sources: [] as string[],
      target: "",
      targets: [] as string[]
    };
    if (menuItem.type === "Outgoing") {
      obj.sources = modelIds;
      obj.target = selectedId as string;
    } else {
      obj.source = selectedId as string;
      obj.targets = modelIds;
    }
    await modelService.batchCreate({
      ...obj,
      metaclass: relResult.metaclass,
      applyStereotypes: (relResult.appliedStereotypes as StType[]) || [],
      projectId: app.activeProject!.config.id,
      value: relResult.value
    });
  }
}
